//
//  WCNewProjectWindowController.m
//  WabbitCode
//
//  Created by William Towe on 1/7/09.
//  Copyright 2009 Revolution Software. All rights reserved.
//

#import "WCNewProjectWindowController.h"
#import "WCNewProjectCategory.h"
#import "WCNewProjectModel.h"
#import "WCBadgedIconAndTextFieldCell.h"
#import "WCNewProjectOutput.h"
#import "WCMacros.h"
#import "WCNewProjectFromFolderSheetController.h"
#import "WCNewTextFileProcessor.h"
#import "WCProjectGroup.h"
#import "WCBuildTargetsGroup.h"
#import "WCBuildStep.h"
#import "WCErrorsAndWarningsGroup.h"
#import "NSResponder+WCExtensions.h"
#import "WCAppController.h"
#import "WCTextFile.h"
#import "WCProject.h"
#import "WCBuildConfiguration.h"
#import "WCBookmarksGroup.h"
#import "WCProjectSymbolsGroup.h"
#import "NSDictionary+WCExtensions.h"
#import "WCBasicPerformer.h"
#import "WCBuildProductsGroup.h"


NSString *kWCNewProjectTemplateInfoShortDescriptionKey = @"shortDescription";
NSString *kWCNewProjectTemplateInfoLongDescriptionKey = @"longDescription";
NSString *kWCNewProjectTemplateInfoTargetModelKey = @"targetModel";
NSString *kWCNewProjectTemplateInfoTargetOutputKey = @"targetOutput";
NSString *kWCNewProjectTemplateInfoIconNameKey = @"iconName";
NSString *kWCNewProjectTemplateInfoIncludeFilesKey = @"includeFiles";

#define kWCNewProjectTemplateInfoName @"templateInfo.plist"
#define kWCNewProjectTemplatesDirectory @"Project Templates"

@implementation WCNewProjectWindowController
#pragma mark *** Subclass Overrides ***
- (id)init {
	if (!(self = [super initWithWindowNibName:@"WCNewProjectWindow"]))
		return nil;
	
	_newProjectCategories = [[NSMutableArray alloc] init];
	
	return self;
}

- (void)dealloc {
	[_newProjectCategories release];
	[super dealloc];
}

- (void)windowWillLoad {
	[super windowWillLoad];
	
	// load the built-in templates first
	WCNewProjectCategory *builtInCategory = [WCNewProjectCategory newProjectCategoryWithName:NSLocalizedString(@"Models",@"new project models category")];
	NSString *projectTemplatesPath = [[NSBundle mainBundle] pathForResource:kWCNewProjectTemplatesDirectory ofType:@""];
	NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
	NSString *userProjectTemplatesPath = nil;
	
	if ([searchPaths count])
		userProjectTemplatesPath = [[[searchPaths objectAtIndex:0] stringByAppendingPathComponent:[[NSProcessInfo processInfo] processName]] stringByAppendingPathComponent:kWCNewProjectTemplatesDirectory];
	
	for (NSString *modelName in [[NSFileManager defaultManager] directoryContentsAtPath:projectTemplatesPath]) {
		WCNewProjectModel *model = [WCNewProjectModel newProjectModelWithName:modelName];
		NSString *modelPath = [projectTemplatesPath stringByAppendingPathComponent:modelName];
		BOOL isDirectory = NO;
		
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		// create the same group in user project templates folder if it doesn't already exist
		if (userProjectTemplatesPath) {
			NSString *userProjectTemplatesGroupPath = [userProjectTemplatesPath stringByAppendingPathComponent:modelName];
			if (![[NSFileManager defaultManager] fileExistsAtPath:userProjectTemplatesGroupPath isDirectory:&isDirectory] || !isDirectory) {
				NSError *error = nil;
				if (![[NSFileManager defaultManager] createDirectoryAtPath:userProjectTemplatesGroupPath withIntermediateDirectories:YES attributes:nil error:&error]) {
					// TODO: display the error?
				}
			}
		}
		
		for (NSString *outputName in [[NSFileManager defaultManager] directoryContentsAtPath:modelPath]) {
			
			NSString *templatePath = [modelPath stringByAppendingPathComponent:outputName];
			
			if (![[NSFileManager defaultManager] fileExistsAtPath:templatePath isDirectory:&isDirectory] || !isDirectory)
				continue;
			
			NSString *templateInfoPath = [templatePath stringByAppendingPathComponent:kWCNewProjectTemplateInfoName];
			
			if (![[NSFileManager defaultManager] fileExistsAtPath:templateInfoPath])
				continue;
			
			NSDictionary *templateInfo = [NSDictionary dictionaryWithContentsOfFile:templateInfoPath];
			// make sure the template info plist contains the necessary keys
			if (![templateInfo isValidNewProjectTemplateInfoPlist])
				continue;
			
			WCNewProjectOutput *output = [WCNewProjectOutput newProjectOutputWithName:outputName templateInfo:templateInfo templateDirectory:templatePath];
			
			[[model mutableChildNodes] addObject:output];
		}
		[pool release];
		
		if ([[model childNodes] count])
			[[builtInCategory mutableChildNodes] addObject:model];
	}
	
	if ([[builtInCategory childNodes] count])
		[[self newProjectCategories] addObject:builtInCategory];
	
	WCNewProjectCategory *otherCategory = [WCNewProjectCategory newProjectCategoryWithName:NSLocalizedString(@"Other",@"new project other category")];
	
	// add the user templates	
	
	// the application support directory has been moved
	if (!userProjectTemplatesPath)
		return;
	
	for (NSString *modelName in [[NSFileManager defaultManager] directoryContentsAtPath:userProjectTemplatesPath]) {
		BOOL usingAnExistingModel = NO;
		WCNewProjectModel *model = nil;
		// check the default model names
		for (WCNewProjectModel *existingModel in [builtInCategory childNodes]) {
			if ([modelName isEqualToString:[existingModel name]]) {
				model = existingModel;
				usingAnExistingModel = YES;
				break;
			}
		}
		if (!model)
			model = [WCNewProjectModel newProjectModelWithName:modelName];
		NSString *modelPath = [userProjectTemplatesPath stringByAppendingPathComponent:modelName];
		
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		for (NSString *outputName in [[NSFileManager defaultManager] directoryContentsAtPath:modelPath]) {
			
			NSString *templatePath = [modelPath stringByAppendingPathComponent:outputName];
			BOOL isDirectory = NO;
			
			if (![[NSFileManager defaultManager] fileExistsAtPath:templatePath isDirectory:&isDirectory] || !isDirectory)
				continue;
			
			NSString *templateInfoPath = [templatePath stringByAppendingPathComponent:kWCNewProjectTemplateInfoName];
			
			if (![[NSFileManager defaultManager] fileExistsAtPath:templateInfoPath])
				continue;
			
			NSDictionary *templateInfo = [NSDictionary dictionaryWithContentsOfFile:templateInfoPath];
			
			// make sure the template info plist contains the necessary keys
			if (![templateInfo isValidNewProjectTemplateInfoPlist])
				continue;
			
			WCNewProjectOutput *output = [WCNewProjectOutput newProjectOutputWithName:outputName templateInfo:templateInfo templateDirectory:templatePath];
			
			[[model mutableChildNodes] addObject:output];
		}
		[pool release];
		
		if (!usingAnExistingModel && [[model childNodes] count])
			[[otherCategory mutableChildNodes] addObject:model];
	}
	
	if ([[otherCategory childNodes] count])
		[[self newProjectCategories] addObject:otherCategory];
}

- (void)windowDidLoad {
	[super windowDidLoad];
	
	[[self window] setContentBorderThickness:32.0 forEdge:NSMinYEdge];
	
	[[self window] setTitle:NSLocalizedString(@"New Project",@"title of new project window")];
	
	for (NSTreeNode *node in [[[_outlineView dataSource] arrangedObjects] childNodes]) {
		[_outlineView expandItem:node];
	}
	
	[[_outlineView dataSource] setSelectionIndexPath:[[NSIndexPath indexPathWithIndex:0] indexPathByAddingIndex:0]];
}

- (IBAction)showWindow:(id)sender {
	[[self window] center];
	[super showWindow:sender];
}
#pragma mark NSSplitView Delegate
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset {
	if ([splitView isVertical])
		return proposedMin + 150.0;
	else if (![splitView isVertical])
		return proposedMin + 100.0;
	return proposedMin;
}

- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset {
	if ([splitView isVertical])
		return proposedMax - 250.0;
	else if (![splitView isVertical])
		return proposedMax - 125.0;
	return proposedMax;
}

- (NSRect)splitView:(NSSplitView *)splitView additionalEffectiveRectOfDividerAtIndex:(NSInteger)dividerIndex {
	if ([splitView isVertical]) {
		return NSMakeRect(NSMaxX([_gradientBarView bounds]) - [_leftSplitterHandleImageView frame].size.width, [splitView frame].size.height - [_gradientBarView frame].origin.y - [_gradientBarView bounds].size.height, [_leftSplitterHandleImageView frame].size.width, [_gradientBarView bounds].size.height);
	}
	return NSZeroRect;
}

- (void)splitView:(NSSplitView *)splitView resizeSubviewsWithOldSize:(NSSize)oldSize {
	if ([splitView inLiveResize]) {
		// keep the project outline view and symbols table view the same size while the resizing the middle view
		if ([splitView isVertical]) {
			NSArray *subviews = [splitView subviews];
			NSView *leftView = [subviews objectAtIndex:0];
			NSView *rightView = [subviews lastObject];
			NSRect currentFrame = [splitView frame];
			NSRect leftFrame = [leftView frame];
			NSRect rightFrame = [rightView frame];
			CGFloat dividerThickness = [splitView dividerThickness];
			
			leftFrame.size.height = currentFrame.size.height;
			rightFrame.size.width = currentFrame.size.width - leftFrame.size.width - dividerThickness;
			rightFrame.size.height = currentFrame.size.height;
			rightFrame.origin.x = leftFrame.size.width + dividerThickness;
			
			[leftView setFrame:leftFrame];
			[rightView setFrame:rightFrame];
		}
		// keep the top view in the middle split view the same while resizing the bottom view
		else {
			NSArray *subviews = [splitView subviews];
			NSView *topView = [subviews objectAtIndex:0];
			NSView *bottomView = [subviews lastObject];
			NSRect currentFrame = [splitView frame];
			NSRect topFrame = [topView frame];
			NSRect bottomFrame = [bottomView frame];
			CGFloat dividerThickness = [splitView dividerThickness];
			
			bottomFrame.size.width = currentFrame.size.width;
			topFrame.size.height = currentFrame.size.height - bottomFrame.size.height - dividerThickness;
			topFrame.size.width = currentFrame.size.width;
			bottomFrame.origin.y = topFrame.size.height + dividerThickness;
			
			[topView setFrame:topFrame];
			[bottomView setFrame:bottomFrame];
		}
	}
	else {
		[splitView adjustSubviews];
	}
}
#pragma mark NSOutlineView Delegate
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
	if ([[item representedObject] isKindOfClass:[WCNewProjectModel class]]) {
		[cell setBadgeCount:[[[item representedObject] childNodes] count]];
	}
	else {
		[cell setBadgeCount:0];
	}
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
	return (![[item representedObject] isLeaf]);
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
	return [[item representedObject] isLeaf];
}
#pragma mark IBActions
- (IBAction)approveModalWindowAction:(id)sender; {
	NSSavePanel *panel = [NSSavePanel savePanel];
	
	[panel setRequiredFileType:@"org.revsoft.wabbitcode.project"];
	
	[panel beginSheetForDirectory:NSHomeDirectory() file:nil modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(_createNewProjectSavePanelDidEnd:code:info:) contextInfo:NULL];
}
#pragma mark *** Public Methods ***
+ (WCNewProjectWindowController *)sharedInstance; {
	static id _sharedInstance = nil;
	if (!_sharedInstance) {
		_sharedInstance = [[[self class] alloc] init];
	}
	return _sharedInstance;
}

- (void)presentNewProjectWindow; {
	NSInteger result = [NSApp runModalForWindow:[self window]];
	
	if (result != NSOKButton)
		return;
	
	// save changes to the preferences only when the user chooses to create a project with the current settings
}
- (BOOL)createNewProjectAtPath:(NSString *)path withOutput:(WCNewProjectOutput *)output error:(NSError **)error; {
	NSString *projectDirectoryPath = [path stringByDeletingPathExtension];
	
	// check to see if a directory with the filename already exists
	BOOL isDirectory = NO;
	if ([[NSFileManager defaultManager] fileExistsAtPath:projectDirectoryPath isDirectory:&isDirectory] && isDirectory) {
		if (error) {
			// TODO: construct an error
		}
		NSLog(@"the project directory already exists at %@", projectDirectoryPath);
		return NO;
	}
	
	// create the project directory
	if (![[NSFileManager defaultManager] createDirectoryAtPath:projectDirectoryPath attributes:nil]) {
		if (error) {
			// TODO: construct an error
			
		}
		NSLog(@"failed to create the project directory at %@", projectDirectoryPath);
		return NO;
	}
	
	// copy all files from the template folder into the project directory, excluding the templateInfo.plist file and hidden files
	NSString *templateDirectoryPath = [output templateDirectory];
	for (NSString *fileName in [[NSFileManager defaultManager] directoryContentsAtPath:templateDirectoryPath]) {
		if ([fileName hasPrefix:@"."])
			continue;
		else if ([fileName isEqualToString:kWCNewProjectTemplateInfoName])
			continue;
		
		if(![[NSFileManager defaultManager] copyItemAtPath:[templateDirectoryPath stringByAppendingPathComponent:fileName] toPath:[projectDirectoryPath stringByAppendingPathComponent:fileName] error:error]) {
			// TODO: display the error
			NSLog(@"unable to copy item at %@ to %@", [templateDirectoryPath stringByAppendingPathComponent:fileName], [projectDirectoryPath stringByAppendingPathComponent:fileName]);
		}
	}
	
	if (![[WCBasicPerformer sharedInstance] copyIncludeFiles:[output includeFiles] toProjectDirectory:projectDirectoryPath includedFilePaths:NULL error:error]) {
		// TODO: display the error
	}
	
	// create the main assembly file
	NSString *defaultFile = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"default" ofType:@"txt"] encoding:NSUTF8StringEncoding error:error];
	NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[[projectDirectoryPath lastPathComponent] stringByAppendingPathExtension:@"asm"], WCNewTextFileProcessorFileNameKey, [projectDirectoryPath lastPathComponent], WCNewTextFileProcessorProjectNameKey, nil];
	NSData *mainAssemblyFileData = [[WCNewTextFileProcessor sharedInstance] dataByReplacingPlaceholdersInString:defaultFile usingEncoding:NSUTF8StringEncoding withAttributes:attributes];
	
	// write the file to disk
	if (![[NSFileManager defaultManager] createFileAtPath:[projectDirectoryPath stringByAppendingPathComponent:[[projectDirectoryPath lastPathComponent] stringByAppendingPathExtension:@"asm"]] contents:mainAssemblyFileData attributes:nil]) {
		if (error) {
			// TODO: create an error
		}
		NSLog(@"failed to write the main assembly file to disk");
		return NO;
	}
	
	// create the project wrapper file
	NSString *projectWrapperPath = [projectDirectoryPath stringByAppendingPathComponent:[path lastPathComponent]];
	NSFileWrapper *projectWrapper = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
	
	// write the wrapper file to disk
	if (![projectWrapper writeToFile:projectWrapperPath atomically:YES updateFilenames:NO]) {
		if (error) {
			// TODO: create an error
		}
		NSLog(@"failed to write the project wrapper file to disk");
		return NO;
	}
	
	// copy the default project preferences file into the wrapper file
	NSString *projectPreferencesPath = [projectWrapperPath stringByAppendingPathComponent:[NSUserName() stringByAppendingPathExtension:@"wcodeprefs"]];
	if (![[NSFileManager defaultManager] copyItemAtPath:[[NSBundle mainBundle] pathForResource:@"default" ofType:@"wcodeprefs"] toPath:projectPreferencesPath error:error]) {
		// TODO: display the error
		NSLog(@"failed to copy the default project preferences file into the project wrapper");
		return NO;
	}
	
	// create the project data file
	// create the project group
	WCProjectGroup *projectGroup = [WCProjectGroup projectGroup];
	[projectGroup recursivelyAddFilePathsFromFolderPath:projectDirectoryPath];
	
	// create the build targets group
	WCBuildTargetsGroup *buildTargetsGroup = [WCBuildTargetsGroup buildTargetsGroup];
	WCBuildTarget *initialBuildTarget = [WCBuildTarget buildTargetWithModel:[output targetModel] outputType:[output targetOutput] active:YES];
	for (WCBuildConfiguration *config in [initialBuildTarget buildConfigurations])
		[config recursivelyAddIncludeDirectoriesWithDirectoryPath:projectDirectoryPath];
	[[buildTargetsGroup mutableChildNodes] addObject:initialBuildTarget];
	
	WCFile *file = [projectGroup fileWithFileName:[[projectDirectoryPath lastPathComponent] stringByAppendingPathExtension:@"asm"]];
	if (file) {
		WCBuildStep *initialBuildStep = [WCBuildStep buildStepWithStepType:WCBSStepTypeAssembleFile file:file];
		[[initialBuildTarget mutableChildNodes] addObject:initialBuildStep];
	}
	
	// create the build results group
	WCBuildProductsGroup *buildResultsGroup = [WCBuildProductsGroup buildProductsGroup];
	
	// create the errors and warnings group
	WCErrorsAndWarningsGroup *errorsAndWarningsGroup = [WCErrorsAndWarningsGroup errorsAndWarningsGroup];
	
	// create the bookmarks group
	WCBookmarksGroup *bookmarksGroup = [WCBookmarksGroup bookmarksGroup];
	
	// create the project symbols group
	WCProjectSymbolsGroup *projectSymbolsGroup = [WCProjectSymbolsGroup projectSymbolsGroup];
	
	NSMutableArray *projectGroups = [NSMutableArray arrayWithObjects:projectGroup, buildTargetsGroup, buildResultsGroup, errorsAndWarningsGroup, bookmarksGroup, projectSymbolsGroup, nil];
	NSData *projectData = NSKeyedArchivedObject(projectGroups);
	
	if (![projectData writeToFile:[projectWrapperPath stringByAppendingPathComponent:@"project.wcodedata"] options:NSAtomicWrite error:error]) {
		// TODO: display the error
		NSLog(@"failed to write project data file to disk");
		return NO;
	}
	
	if (![[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:projectWrapperPath isDirectory:YES] display:YES error:error]) {
		// TODO: display the error
		NSLog(@"failed to open the document");
		return NO;
	}
	
	return YES;
}

- (BOOL)createNewProjectAtPath:(NSString *)path forTargetModel:(WCBTModel)model targetOutputType:(WCBTOutputType)outputType mainAssemblyFilePath:(NSString *)mainAssemblyFilePath usingEncoding:(NSStringEncoding)encoding error:(NSError **)error; {
	// create the project wrapper file
	NSString *projectDirectoryPath = path;
	NSString *projectWrapperPath = [projectDirectoryPath stringByAppendingPathComponent:[[path lastPathComponent] stringByAppendingPathExtension:@"wcodeproj"]];
	NSFileWrapper *projectWrapper = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
	
	// write the wrapper file to disk
	if (![projectWrapper writeToFile:projectWrapperPath atomically:YES updateFilenames:NO]) {
		if (error) {
			// TODO: create an error
		}
		NSLog(@"failed to write the project wrapper file to disk");
		return NO;
	}
	
	// copy the default project preferences file into the wrapper file
	NSString *projectPreferencesPath = [projectWrapperPath stringByAppendingPathComponent:[NSUserName() stringByAppendingPathExtension:@"wcodeprefs"]];
	if (![[NSFileManager defaultManager] copyItemAtPath:[[NSBundle mainBundle] pathForResource:@"default" ofType:@"wcodeprefs"] toPath:projectPreferencesPath error:error]) {
		// TODO: display the error
		NSLog(@"failed to copy the default project preferences file into the project wrapper");
		return NO;
	}
	
	// create the project data file
	// create the project group
	WCProjectGroup *projectGroup = [WCProjectGroup projectGroup];
	[projectGroup recursivelyAddFilePathsFromFolderPath:projectDirectoryPath usingEncoding:encoding];
	
	// create the build targets group
	WCBuildTargetsGroup *buildTargetsGroup = [WCBuildTargetsGroup buildTargetsGroup];
	WCBuildTarget *initialBuildTarget = [WCBuildTarget buildTargetWithModel:model outputType:outputType active:YES];
	for (WCBuildConfiguration *config in [initialBuildTarget buildConfigurations])
		[config recursivelyAddIncludeDirectoriesWithDirectoryPath:projectDirectoryPath];
	[[buildTargetsGroup mutableChildNodes] addObject:initialBuildTarget];
	WCFile *initialFile = [projectGroup fileWithFileName:[mainAssemblyFilePath lastPathComponent]];
	if (initialFile) {
		WCBuildStep *initialBuildStep = [WCBuildStep buildStepWithStepType:WCBSStepTypeAssembleFile file:initialFile];
		[[initialBuildTarget mutableChildNodes] addObject:initialBuildStep];
	}
	
	// create the build results group
	WCBuildProductsGroup *buildProductsGroup = [WCBuildProductsGroup buildProductsGroup];
	
	// create the errors and warnings group
	WCErrorsAndWarningsGroup *errorsAndWarningsGroup = [WCErrorsAndWarningsGroup errorsAndWarningsGroup];
	
	// create the bookmarks group
	WCBookmarksGroup *bookmarksGroup = [WCBookmarksGroup bookmarksGroup];
	
	// create the project symbols group
	WCProjectSymbolsGroup *projectSymbolsGroup = [WCProjectSymbolsGroup projectSymbolsGroup];
	
	NSMutableArray *projectGroups = [NSMutableArray arrayWithObjects:projectGroup, buildTargetsGroup, buildProductsGroup, errorsAndWarningsGroup, bookmarksGroup, projectSymbolsGroup, nil];
	NSData *projectData = NSKeyedArchivedObject(projectGroups);
	
	if (![projectData writeToFile:[projectWrapperPath stringByAppendingPathComponent:@"project.wcodedata"] options:NSAtomicWrite error:error]) {
		// TODO: display the error
		NSLog(@"failed to write project data file to disk");
		return NO;
	}
	
	WCProject *project = nil;
	if (!(project = [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:projectWrapperPath isDirectory:YES] display:YES error:error])) {
		// TODO: display the error
		return NO;
	}
	
	// select our initial file if its a text file
	if ([initialFile isKindOfClass:[WCTextFile class]]) {
		[project addTabViewItemForTextFile:(WCTextFile *)initialFile inTabViewContext:project];
	}
	
	return YES;
}
#pragma mark Accessors
@synthesize newProjectCategories=_newProjectCategories;
#pragma mark IBActions
- (IBAction)createNewProjectFromFolderAction:(id)sender; {
	[WCNewProjectFromFolderSheetController presentNewProjectFromFolderSheet];
}
#pragma mark *** Private Methods ***

#pragma mark Callbacks
- (void)_createNewProjectSavePanelDidEnd:(NSSavePanel *)panel code:(NSInteger)code info:(void *)info {
	// make sure the panel closes before proceeding
	[panel close];
	if (code != NSOKButton)
		return;
	
	WCNewProjectOutput *output = [[_arrayController selectedObjects] objectAtIndex:0];
	
	if (!output)
		return;
	
	NSError *error = nil;
	if (![self createNewProjectAtPath:[panel filename] withOutput:output error:&error]) {
		// TODO: display the error
		return;
	}
	
	[super approveModalWindowAction:nil];
}
@end
